package com.sinodata.bsm.cicp.collector.mail;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.net.pop3.POP3Client;
import org.apache.commons.net.pop3.POP3MessageInfo;
import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.common.constants.DataTypeConstants;
import com.sinodata.bsm.common.vo.ResPropertyValue;

public class MailCollector extends Collector {

    private static Logger logger = Logger.getLogger(MailCollector.class);

    public MailCollector() {

    }

    /*
     * (non-Javadoc)
     * @see com.sinodata.bsm.cicp.collector.Collector#collect(java.lang.String)
     */
    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        String send_success = sendMail();
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        POP3Client pop3_client = new POP3Client();
        //接收邮件的邮箱地址
        String receiveBox = this.getParamMap().get("Email_Address");//接收方邮箱地址
        //邮箱帐户
        String receive_userName = receiveBox.split("@")[0];
        //邮箱密码
        String receive_password = this.getParamMap().get("Email_Password");//接收方邮箱密码
        String sendBox = this.getParamMap().get("Email_Address");//发送方邮箱地址
        String message_time = "";
        String interval_time = "";
        try {
            pop3_client.connect(this.getParamMap().get("Receiver_Email_POP_Settings"), 110);//接收方邮箱POP设置
            boolean login = pop3_client.login(receive_userName, receive_password);
            if (!login) {
                logger.error("Failed to login mail server of receiver!");
            }
            boolean flag = false;
            if (login) {
                POP3MessageInfo[] messages = pop3_client.listMessages();//获得收件箱邮件列表
                POP3MessageInfo[] mails = messages;
                Reader reader = null;
                BufferedReader bufferReader = null;

                for (int i = mails.length; i > 0; i--) {
                    flag = false;
                    message_time = "";
                    reader = pop3_client.retrieveMessage(i);//读取邮件
                    bufferReader = new java.io.BufferedReader(reader);
                    String line = bufferReader.readLine();
                    while (line != null) {
                        if (line.contains("Date: ")) {
                            message_time = getMailDate(line);
                        }
                        if (line.contains("From: ") && line.contains(sendBox)) {
                            flag = true;
                        }
                        if (flag && !message_time.equals("")) {
                            i = 0;
                            break;
                        } else {
                            line = bufferReader.readLine();
                        }
                    }
                    if (i == 1 && !flag) {
                        message_time = "";
                    }
                }

                if (!message_time.equals("")) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String currentTime = sdf.format(new Date());
                    try {
                        java.text.DecimalFormat df = new java.text.DecimalFormat("#.#");
                        double time = (sdf.parse(currentTime).getTime() - sdf.parse(message_time).getTime()) / 1000 / 60.0;
                        interval_time = df.format(time);
                    } catch (ParseException e) {
                        logger.error(e);
                        throw new CollectorException(e);
                    } finally {
                        try {
                            if (pop3_client != null) {
                                pop3_client.disconnect();
                                pop3_client = null;
                            }
                        } catch (IOException e) {
                            logger.error("Failed to close the connection of mail server!", e);
                            throw new CollectorException("Failed to close the connection of mail server!", e);
                        }
                    }
                }

                if (bufferReader != null) {
                    try {
                        bufferReader.close();
                    } catch (Exception e) {
                    }
                    bufferReader = null;
                }
            }
        } catch (Exception e) {
            logger.error("Failed to login the mail server!", e);
            throw new CollectorException("Failed to login the mail server!", e);
        } finally {
            try {
                if (pop3_client != null) {
                    pop3_client.disconnect();
                }
            } catch (IOException e) {
                logger.error("Failed to close the connection of the mail server!", e);
                throw new CollectorException("Failed to close the connection of the mail server!", e);
            }
        }
        ResPropertyValue v = new ResPropertyValue();
        String[] propMetas = this.getPropMeta();
        ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
        propValues[2] = ResPropertyValue.createPropValue(send_success, propMetas[2]);
        propValues[0] = ResPropertyValue.createPropValue(message_time, propMetas[0]);
        propValues[1] = ResPropertyValue.createPropValue(interval_time, propMetas[1]);
        v.setValues(propValues);
        values.add(v);

        return values;
    }

    //发送邮件
    public String sendMail() {
        String mail_to = this.getParamMap().get("Email_Address");//接收方邮箱地址
        String mail_from = this.getParamMap().get("Email_Address");//发送方邮箱地址
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String subject = sdf.format(new Date());
        String title = subject;
        //String host = "smtp." + mail_from.split("@")[1];
        String host = this.getParamMap().get("Sender_Email_POP_Settings");
        Properties props = new Properties();
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.auth", "true");

        Session s = Session.getInstance(props);
        //s.setDebug(true);

        MimeMessage message = new MimeMessage(s);
        Transport transport = null;
        //  给消息对象设置发件人/收件人/主题/发信时间
        try {
            InternetAddress from = new InternetAddress(mail_from);
            message.setFrom(from);
            InternetAddress to = new InternetAddress(mail_to);
            message.setRecipient(Message.RecipientType.TO, to);
            message.setSubject(title);
            message.setSentDate(new Date());

            //  给消息对象设置内容
            BodyPart mdp = new MimeBodyPart();//新建一个存放信件内容的BodyPart对象
            mdp.setContent(subject, "text/html;charset=gb2312");//给BodyPart对象设置内容和格式/编码方式
            Multipart mm = new MimeMultipart();//新建一个MimeMultipart对象用来存放BodyPart对

            mm.addBodyPart(mdp);//将BodyPart加入到MimeMultipart对象中(可以加入多个BodyPart)
            message.setContent(mm);//把mm作为消息对象的内容

            message.saveChanges();
            transport = s.getTransport("smtp");
            //此判断主要适用于江西内网邮箱监控
            //            if (mail_from.trim().equals("jx_glxx@jx.chinaunicom.com")) {
            //                mail_from = mail_from.split("@")[0];
            //            }
            transport.connect(host, mail_from, this.getParamMap().get("Email_Password"));//发送方邮箱密码
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
        } catch (Exception e) {
            logger.error("Failed to monitor the send mail!", e);
            try {
                transport.close();
            } catch (MessagingException e1) {
                logger.error(e);
            }
            //return "NO"
            return DataTypeConstants.BOOLEAN_VALUE_FALSE;
        }
        //return "YES";
        return DataTypeConstants.BOOLEAN_VALUE_TRUE;
    }

    private String getMailDate(String dateStr) {
        String str[] = dateStr.split(" ");
        String month = "-";
        String result = "";
        String[] months = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
        if (dateStr.indexOf(",") != -1) {
            for (int i = 0; i < months.length; i++) {
                if (months[i].equals(str[3])) {
                    month = i + 1 + "";
                }
            }
            result = str[4] + "-" + month + "-" + str[2] + " " + str[5];
        } else {
            for (int j = 0; j < months.length; j++) {
                if (months[j].equals(str[2])) {
                    month = j + 1 + "";
                }
            }
            result = str[3] + "-" + month + "-" + str[1] + " " + str[4];
        }

        return result;

    }

    @Override
    public String[] getParamMeta() {
        //        return new String[] { "发送方邮箱地址", "发送方邮箱密码", "接收方邮箱POP设置", "接收方邮箱地址", "接收方邮箱密码" };
        //return new String[] { "Sender E-mail", "Sender E-mail Password", "Receiver E-mail POP Settings", "Receiver E-mail", "Receiver E-mail Password" };
        return new String[] { "Email_Address", "Email_Password", "Receiver_Email_POP_Settings", "Sender_Email_POP_Settings" };
    }

    @Override
    public String[] getPropMeta() {
        //        return new String[] { "上次接收到邮件的时间", "当前与上次收到邮件的时间间隔", "发送方邮件是否发送成功" };
        return new String[] { "$1", "$2", "$3" };
    }

    public static void main(String[] args) {
        MailCollector maiCollector = new MailCollector();
        try {
            //			maiCollector.collect("localhost");
            System.out.println(maiCollector.collect("localhost"));
        } catch (CollectorException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
